﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcWiki.Model;

namespace MvcWiki.Repository
{
    public class UnitOfWork : IUnitOfWork
    {
        Dictionary<WikiNamespace, IUnitOfWorkPersistence> SelectedWikiNamespaces = new Dictionary<WikiNamespace, IUnitOfWorkPersistence>();
        Dictionary<WikiPage, IUnitOfWorkPersistence> SelectedWikiPages = new Dictionary<WikiPage, IUnitOfWorkPersistence>();

        Dictionary<WikiNamespace, IUnitOfWorkPersistence> SavedWikiNamespaces = new Dictionary<WikiNamespace, IUnitOfWorkPersistence>();
        Dictionary<WikiPage, IUnitOfWorkPersistence> SavedWikiPages = new Dictionary<WikiPage, IUnitOfWorkPersistence>();

        Dictionary<WikiNamespace, IUnitOfWorkPersistence> DeletedWikiNamespaces = new Dictionary<WikiNamespace, IUnitOfWorkPersistence>();
        Dictionary<WikiPage, IUnitOfWorkPersistence> DeletedWikiPages = new Dictionary<WikiPage, IUnitOfWorkPersistence>();

        public void Selected(Entity entity, IUnitOfWorkPersistence persistence)
        {
            if (entity is WikiNamespace)
            {
                var wikiNamespace = entity as WikiNamespace;

                if (!SelectedWikiNamespaces.ContainsKey(wikiNamespace))
                {
                    SelectedWikiNamespaces.Add(wikiNamespace, persistence);
                }
            }
            else if (entity is WikiPage)
            {
                var wikiPage = entity as WikiPage;

                if (!SelectedWikiPages.ContainsKey(wikiPage))
                {
                    SelectedWikiPages.Add(entity as WikiPage, persistence);
                }
            }
        }

        public void Saved(Entity entity, IUnitOfWorkPersistence persistence)
        {
            if (entity is WikiNamespace)
            {
                SavedWikiNamespaces.Add(entity as WikiNamespace, persistence);
            }
            else if (entity is WikiPage)
            {
                SavedWikiPages.Add(entity as WikiPage, persistence);
            }
        }

        public void Deleted(Entity entity, IUnitOfWorkPersistence persistence)
        {
            if (entity is WikiNamespace)
            {
                DeletedWikiNamespaces.Add(entity as WikiNamespace, persistence);
            }
            else if (entity is WikiPage)
            {
                DeletedWikiPages.Add(entity as WikiPage, persistence);
            }
        }

        public void Commit()
        {
            foreach (KeyValuePair<WikiNamespace, IUnitOfWorkPersistence> kvp in SavedWikiNamespaces)
            {
                if (SelectedWikiNamespaces.ContainsKey(kvp.Key))
                {
                    kvp.Value.UpdateEntity(kvp.Key);
                }
                else
                {
                    kvp.Value.InsertEntity(kvp.Key);
                }
            }

            foreach (KeyValuePair<WikiPage, IUnitOfWorkPersistence> kvp in SavedWikiPages)
            {
                if (SelectedWikiPages.ContainsKey(kvp.Key))
                {
                    kvp.Value.UpdateEntity(kvp.Key);
                }
                else
                {
                    kvp.Value.InsertEntity(kvp.Key);
                }
            }

            foreach (KeyValuePair<WikiPage, IUnitOfWorkPersistence> kvp in DeletedWikiPages)
            {
                if (SelectedWikiPages.ContainsKey(kvp.Key))
                {
                    kvp.Value.DeleteEntity(kvp.Key);
                }
            }

            foreach (KeyValuePair<WikiNamespace, IUnitOfWorkPersistence> kvp in DeletedWikiNamespaces)
            {
                if (SelectedWikiNamespaces.ContainsKey(kvp.Key))
                {
                    kvp.Value.DeleteEntity(kvp.Key);
                }
            }

            SelectedWikiNamespaces.Clear();
            SelectedWikiPages.Clear();

            SavedWikiNamespaces.Clear();
            SavedWikiPages.Clear();

            DeletedWikiNamespaces.Clear();
            DeletedWikiPages.Clear();
        }
    }
}
